package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.dto.UserDetail;
import com.leyou.auth.utils.UserContext;
import com.leyou.common.exception.LyException;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderDTO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.OrderDetailService;
import com.leyou.trade.service.OrderLogisticsService;
import com.leyou.trade.service.OrderService;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.AddressDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private OrderDetailService orderDetailService;


    @Autowired
    private UserClient userClient;

    @Autowired
    private OrderLogisticsService orderLogisticsService;

    @Override
    @Transactional
    public Long createOrder(OrderDTO orderDTO) {

        //调用过滤器获取用户信息
        UserDetail user = UserContext.getUser();

        //服务端必须对客户端请求的数据进行校验
        if (orderDTO == null
                || CollectionUtils.isEmpty(orderDTO.getCarts())
                || orderDTO.getAddressId() == null
                || orderDTO.getPaymentType() == null) {
            throw new LyException(400, "请正确提交订单");
        }

        //保存数据
        Order order = new Order();
        order.setStatus(1);
        order.setUserId(user.getId());
        order.setPostFee(0L);

        Integer paymentType = orderDTO.getPaymentType() > 2 || orderDTO.getPaymentType() < 1 ? 4 : orderDTO.getPaymentType();

        if (paymentType == 4 ) {
            throw new LyException(400,"支付方式有误");
        }

        order.setPaymentType(paymentType);

        //key是skuId，value商品数量
        Map<Long, Integer> carts = orderDTO.getCarts();

        //实际下单的商品的集合
        List<SkuDTO> skuDTOS = this.itemClient.listSkuBySpuIds(new ArrayList<>(carts.keySet()));

        long totalPrice=0;
        //总价：单价*数量并且累计
        for (SkuDTO skuDTO : skuDTOS) {
            totalPrice += skuDTO.getPrice()*carts.get(skuDTO.getId());
        }


        //因该支付的总额
        order.setTotalFee(totalPrice);
        //实际支付的总额,包邮无优惠
        order.setActualFee(totalPrice);


        this.save(order);

        //订单详情

        List<OrderDetail> orderDetails = skuDTOS.stream().map(skuDTO -> {
            OrderDetail orderDetail = new OrderDetail();

            orderDetail.setOrderId(order.getOrderId());
            orderDetail.setSkuId(skuDTO.getId());
            orderDetail.setNum(carts.get(skuDTO.getId()));
            orderDetail.setTitle(skuDTO.getTitle());
            orderDetail.setPrice(skuDTO.getPrice());
            orderDetail.setSpec(skuDTO.getSpecialSpec());
            orderDetail.setImage(StringUtils.substringBefore(skuDTO.getImages(), ","));
            return orderDetail;
        }).collect(Collectors.toList());

        //批量保存订单详情
        this.orderDetailService.saveBatch(orderDetails);

        AddressDTO addressDTO = this.userClient.queryAddressById(orderDTO.getAddressId(), user.getId());

        if (null == addressDTO) {
            throw new LyException(400,"请选择正确收获地址");
        }

        OrderLogistics orderLogistics = new OrderLogistics();

        BeanUtils.copyProperties(addressDTO,orderLogistics);

        orderLogistics.setOrderId(order.getOrderId());

        this.orderLogisticsService.save(orderLogistics);

        this.itemClient.minusStock(carts);

        return order.getOrderId();
    }
}
